package edu.colorado.core;

import java.io.Serializable;

public class Game implements Serializable
{
    private static final long serialVersionUID = -4354984979504525037L;

    public static enum State { Ok, Win, Loss, Tie }

    public static enum Level { Easy, Medium, Hard }
    
    public static enum Mode { Game, Tournament }

    private Board board;
    private Algorithm ai;
    private Level level;
    private State state;
    private Mode mode;

    public Game(Level level, Mode mode)
    {
        this.level = level;
        this.mode = mode;
        startOver();
    }    

    public void startOver()
    {
        board = new Board();
        state = State.Ok;
        ai = new Algorithm(level, board);
    }

    public State getState() {
        return state;
    }
    
    public Mode getMode() {
        return mode;
    }

    public int getScore() {
        int factor = -1;
        
        switch(level) {
        case Easy:
            factor = 1;
            break;
        case Medium:
            factor = 2;
            break;
        case Hard:
            factor = 3;
            break;
        }

        int score = ai.currentState.score[0] - ai.currentState.score[1];
        
        if (getState() == State.Win) {
            score += 100 * factor;
        } else if (state == State.Loss) {
            score -= 100 * (4 - factor);
        } else if (state == State.Tie) {
            score += 40 * factor;
        }

        return score;
    }

    void printCurrentBoard()
    {
        board.display();
    }

    Integer dropPiece(Integer player, Integer column) // puts a piece in column, returns the row where the piece was dropped
    {
        Integer y = 0;

        while(board.getPiece(column, y) != 2 && ++y < board.getRows())
        {
        }

        if(y == board.getRows())
        {
            return -1;
        }

        board.putPiece(column, y, player);
        //game.updateScore(player, column, y);

        return y;
    }

    public int[] makeMove(int player, int col) {
        int[] coord = null;
        if (state == State.Ok) {
            int row;
            if (player == Algorithm.HUMAN) {
                row = dropPiece(Algorithm.HUMAN, col);
                ai.updateScore(0, col, row);
            } else {
                col = ai.decideMove(Algorithm.DEVICE);
                row = ai.dropPiece(Algorithm.DEVICE, col);
            }
            coord = new int[] { row, col };

            if (isWinner(Algorithm.HUMAN)) {
                state = State.Win;
            } else if (isWinner(Algorithm.DEVICE)) {
                state = State.Loss;
            } else if (isTie()) {
                state = State.Tie;
            } else {
                state = State.Ok;
            }
        }
        return coord;
    }

    public int[][] getFour(int player) {
        return board.getFour(player);
    }

    public Level getLevel() {
        return level;
    }

    public Board getBoard() {
        return board;
    }

    boolean isWinner(Integer player)
    {
        return (ai.isWinner(player));
    }

    boolean isTie()
    {
        return (ai.isTie());
    }
}
